1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package sun.security.jca;
27
28 import java.io.File;
29 import java.lang.reflect.*;
30
31 import java.security.*;
32
33 import sun.security.util.PropertyExpander;
34
35
36
37
38
39
40
41
42
43 final class ProviderConfig {
44
45 private final static sun.security.util.Debug debug =
46 sun.security.util.Debug.getInstance("jca", "ProviderConfig");
47
48
49 private static final String P11_SOL_NAME =
50 "sun.security.pkcs11.SunPKCS11";
51
52
53 private static final String P11_SOL_ARG =
54 "${java.home}/lib/security/sunpkcs11-solaris.cfg";
55
56
57 private final static int MAX_LOAD_TRIES = 30;
58
59
60
61 private final static Class[] CL_STRING = { String.class };
62
63
64 private final String className;
65
66
67
68 private final String argument;
69
70
71 private int tries;
72
73
74 private volatile Provider provider;
75
76
77
78 private boolean isLoading;
79
80 ProviderConfig(String className, String argument) {
81 if (className.equals(P11_SOL_NAME) && argument.equals(P11_SOL_ARG)) {
82 checkSunPKCS11Solaris();
83 }
84 this.className = className;
85 this.argument = expand(argument);
86 }
87
88 ProviderConfig(String className) {
89 this(className, "");
90 }
91
92 ProviderConfig(Provider provider) {
93 this.className = provider.getClass().getName();
94 this.argument = "";
95 this.provider = provider;
96 }
97
98
99
100
101 private void checkSunPKCS11Solaris() {
102 Boolean o = AccessController.doPrivileged(
103 new PrivilegedAction<Boolean>() {
104 public Boolean run() {
105 File file = new File("/usr/lib/libpkcs11.so");
106 if (file.exists() == false) {
107 return Boolean.FALSE;
108 }
109 if ("false".equalsIgnoreCase(System.getProperty
110 ("sun.security.pkcs11.enable-solaris"))) {
111 return Boolean.FALSE;
112 }
113 return Boolean.TRUE;
114 }
115 });
116 if (o == Boolean.FALSE) {
117 tries = MAX_LOAD_TRIES;
118 }
119 }
120
121 private boolean hasArgument() {
122 return argument.length() != 0;
123 }
124
125
126 private boolean shouldLoad() {
127 return (tries < MAX_LOAD_TRIES);
128 }
129
130
131 private void disableLoad() {
132 tries = MAX_LOAD_TRIES;
133 }
134
135 boolean isLoaded() {
136 return (provider != null);
137 }
138
139 public boolean equals(Object obj) {
140 if (this == obj) {
141 return true;
142 }
143 if (obj instanceof ProviderConfig == false) {
144 return false;
145 }
146 ProviderConfig other = (ProviderConfig)obj;
147 return this.className.equals(other.className)
148 && this.argument.equals(other.argument);
149 }
150
151 public int hashCode() {
152 return className.hashCode() + argument.hashCode();
153 }
154
155 public String toString() {
156 if (hasArgument()) {
157 return className + "('" + argument + "')";
158 } else {
159 return className;
160 }
161 }
162
163
164
165
166 synchronized Provider getProvider() {
167
168 Provider p = provider;
169 if (p != null) {
170 return p;
171 }
172 if (shouldLoad() == false) {
173 return null;
174 }
175 if (isLoading) {
176
177
178 if (debug != null) {
179 debug.println("Recursion loading provider: " + this);
180 new Exception("Call trace").printStackTrace();
181 }
182 return null;
183 }
184 try {
185 isLoading = true;
186 tries++;
187 p = doLoadProvider();
188 } finally {
189 isLoading = false;
190 }
191 provider = p;
192 return p;
193 }
194
195
196
197
198
199
200
201
202
203
204
205 private Provider doLoadProvider() {
206 return AccessController.doPrivileged(new PrivilegedAction<Provider>() {
207 public Provider run() {
208 if (debug != null) {
209 debug.println("Loading provider: " + ProviderConfig.this);
210 }
211 try {
212 ClassLoader cl = ClassLoader.getSystemClassLoader();
213 Class<?> provClass;
214 if (cl != null) {
215 provClass = cl.loadClass(className);
216 } else {
217 provClass = Class.forName(className);
218 }
219 Object obj;
220 if (hasArgument() == false) {
221 obj = provClass.newInstance();
222 } else {
223 Constructor<?> cons = provClass.getConstructor(CL_STRING);
224 obj = cons.newInstance(argument);
225 }
226 if (obj instanceof Provider) {
227 if (debug != null) {
228 debug.println("Loaded provider " + obj);
229 }
230 return (Provider)obj;
231 } else {
232 if (debug != null) {
233 debug.println(className + " is not a provider");
234 }
235 disableLoad();
236 return null;
237 }
238 } catch (Exception e) {
239 Throwable t;
240 if (e instanceof InvocationTargetException) {
241 t = ((InvocationTargetException)e).getCause();
242 } else {
243 t = e;
244 }
245 if (debug != null) {
246 debug.println("Error loading provider " + ProviderConfig.this);
247 t.printStackTrace();
248 }
249
250 if (t instanceof ProviderException) {
251 throw (ProviderException)t;
252 }
253
254 if (t instanceof UnsupportedOperationException) {
255 disableLoad();
256 }
257 return null;
258 }
259 }
260 });
261 }
262
263
264
265
266
267
268 private static String expand(final String value) {
269
270 if (value.contains("${") == false) {
271 return value;
272 }
273 return AccessController.doPrivileged(new PrivilegedAction<String>() {
274 public String run() {
275 try {
276 return PropertyExpander.expand(value);
277 } catch (GeneralSecurityException e) {
278 throw new ProviderException(e);
279 }
280 }
281 });
282 }
283
284 }